#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include <pthread.h>
#include "pthread.hpp"
#include "lock_guard.hpp"
#include "Log.hpp"

using namespace pthread_moudle;

#define DEFAULT_NUM 5

template <typename T>
class threadpool
{
private:
    void LockQueue()
    {
        pthread_mutex_lock(&_mutex);
    }
    void UnLockQueue()
    {
        pthread_mutex_unlock(&_mutex);
    }
    void ThreadSleep()
    {
        pthread_cond_wait(&_cond, &_mutex);
    }
    void WakeUpThread()
    {
        // std::cout<<"wakeup"<<std::endl;
        pthread_cond_broadcast(&_cond);
    }
    void WakeUpAllThread()
    {
        pthread_cond_broadcast(&_cond);
    }
    // 将该线程池实现为单例模式，需要将构造函数私有化
    threadpool(int threadnum = DEFAULT_NUM)
        : _threadnum(threadnum),
          _is_running(true)
    {
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }
    void InitThreads()
    {
        for (int i = 0; i < _threadnum; i++)
        {
            std::string name = "thread--" + std::to_string(i + 1);
            _Threads.emplace_back(std::bind(&threadpool::Handlertask, this, std::placeholders::_1), name);
        }
    }
    void StartAll()
    {
        for (auto &thread : _Threads)
            thread.start();
    }
    // 线程处理任务函数，注意：这里会传入this，需要进行处理
    void Handlertask(std::string name)
    {

        while (true)
        {
            // std::cout<<"大傻瓜"<<std::endl;

            LockQueue();

            while (_task_queue.empty())
            {
                // std::cout<<"嘿嘿"<<std::endl;
                ThreadSleep(); // 进入等待
            }

            //  从队列中拿取任务并执行
            T t = _task_queue.front();
           
            _task_queue.pop();
            UnLockQueue();
             t();
        }
    }

public:
    // 以下是可以提供给主线程的成员函数
    static threadpool<T> *GetInstance()
    {
        if (_sigle_instance == nullptr)
        {
            Lockguard lk(_lock); // 防止多个线程同时进入
            _sigle_instance = new threadpool<T>();
            _sigle_instance->InitThreads();
            _sigle_instance->StartAll();
        }
        // Log(DEBUG,"Get Instance success...");
        return _sigle_instance;
    }

    // 禁用拷贝与赋值重载
    threadpool(const threadpool &tp) = delete;
    threadpool &operator=(const threadpool &tp) = delete;

    // 主线程向任务队列插入任务
    void enqueue(T in)
    {
        LockQueue();
        _task_queue.push(in);
        WakeUpThread();
        UnLockQueue();
    }
    void WaitAll()
    {
        for (auto &thread : _Threads)
            thread.join();
    }
    void Stop()
    {
        LockQueue();
        _is_running = false;
        WakeUpAllThread();
        UnLockQueue();
    }
    ~threadpool()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
    }

private:
    int _threadnum;               // 线程池内线程的数量
    std::queue<T> _task_queue;    // 任务队列，不限大小
    std::vector<Thread> _Threads; // 线程数组

    pthread_mutex_t _mutex; // 保护任务队列的锁
    pthread_cond_t _cond;   // 保护任务队列的条件变量

    bool _is_running; // 线程池运行状态
    int _waitnum;     // 线程池内当前正在等待的线程个数

    static threadpool<T> *_sigle_instance;
    static pthread_mutex_t _lock;
};
template <typename T>
threadpool<T> *threadpool<T>::_sigle_instance = nullptr;

template <typename T>
pthread_mutex_t threadpool<T>::_lock = PTHREAD_MUTEX_INITIALIZER;